'use strict';
// Copyright 2014 Blueant Inc. All Rights Reserved.

/**
 * @fileoverview 进入战场
 * @author agl
 */

var _ = require('lodash');
var async = require('async');
var moment = require('moment');
var Code = require('../../../../consts/code');
var moduleType = require('../../../../consts/moduleType');
var operationType = require('../../../../consts/operationType');
var configUtil = require('../../../../util/configUtil');
var constantUtil = require('../../../../util/constantUtil');
var PlayerManager = require('../../../../libs/playerManager');
var atkData = require('../../../../libs/war/atkData');
var arenaData = require('../../../../libs/war/arenaData');
var taskService = require('../../../../services/taskService');
var roleService = require('../../../../services/roleService');
var arenaModel = require('../../../../models/arenaModel.js');
var arenaBattleRecordModel = require('../../../../models/arenaBattleRecordModel.js');

module.exports = function (msg, session, next) {
    var role_id = session.uid;
    var rival_rank = msg.rival_rank;
    var rival_id = msg.rival_id;

    if (!rival_rank || (rival_rank <= 0)) {
        return next(null, {
            code: Code.PARAM_ERROR
        });
    }

    var player_manager = new PlayerManager(role_id);
    var rival_player_manager = new PlayerManager(rival_id);
    var arena_model;
    var rival_arena_model;

    var battle_id;
    var atk_info;
    var def_info;

    var rpt_atk = {};
    var rpt_def = {};

    async.waterfall(
        [

            function (cb) {
                player_manager.refreshData(cb);
            },
            function (cb) {
                player_manager.getModel(['arena', 'accrued'], cb);
            },
            function (cb) {
                rival_player_manager.getModel(['arena', 'role', 'accrued'], cb);
            },
            function (cb) {
                arena_model = player_manager.arena;
                rival_arena_model = rival_player_manager.arena;
                if (rival_arena_model.rank !== rival_rank) {
                    return next(null, {
                        code: Code.ARENA_RANK_CHANGED
                    });
                }

                // 判断挑战CD
                if (arena_model.next_fight_tm > moment().unix()) {
                    return next(null, {
                        code: Code.ARENA_IN_CD_TIME
                    });
                }

                var self_rank = arena_model.rank;
                var role_list = [role_id, rival_id];
                var rank_list = [self_rank, rival_rank];

                arenaModel.lockRoles(role_list, rank_list, function (err, msg_code) {
                    if (!!err) {
                        console.error(err);
                        return next(null, {
                            code: Code.FAIL
                        });
                    }

                    if (!!msg_code) {
                        return next(null, {
                            code: msg_code
                        });
                    }
                    cb();
                });
            },
            function (cb) {
                // 重新取出玩家信息
                player_manager.arena = null;
                player_manager.getModel(['arena', 'role', 'task', 'daily_task', 'achieve', 'accrued'], cb);
            },
            function (cb) {
                // 取出双方战斗信息
                arena_model = player_manager.arena;
                rival_arena_model = rival_player_manager.arena;

                if (!arena_model.decFightTimes()) {
                    return next(null, {
                        code: Code.ARENA_BATTLE_TIME_LIMIT
                    });
                }

                // 加入任务统计
                taskService.addCompleteArenaJoinNum(player_manager);
                _getAtkInfo(role_id, cb);
            },
            function (info, cb) {
                atk_info = info;
                if (rival_arena_model.npc_id) {
                    var npc_info = _getDefNpcInfo(rival_arena_model.npc_id);
                    cb(null, npc_info);
                } else {
                    _getDefPlayerInfo(rival_id, cb);
                }
            },
            function (info, cb) {
                def_info = info;

                rpt_atk.name = atk_info.name;
                rpt_atk.lv = atk_info.lv;
                rpt_atk.job_type = atk_info.job_type;
                rpt_atk.union_name = atk_info.union_name;
                rpt_atk.union_flag = atk_info.union_flag;
                rpt_atk.rank = arena_model.rank;
                rpt_atk.vip = player_manager.role.vip;
                rpt_atk.fight_power = arena_model.att_power;

                rpt_def.name = def_info.name;
                rpt_def.lv = def_info.lv;
                rpt_def.job_type = def_info.job_type;
                rpt_def.union_name = def_info.union_name;
                rpt_def.union_flag = def_info.union_flag;
                rpt_def.rank = rival_arena_model.rank;
                rpt_def.fight_power = rival_arena_model.def_power;

                if (rival_arena_model.npc_id === 0) {
                    _getVipLvl(rival_player_manager, function (err, rival_vip) {
                        rpt_def.vip = rival_vip;
                        cb();
                    });
                } else {
                    cb();
                }
            },
            function (cb) {
                arenaBattleRecordModel.createBattle(role_id, rival_id, rpt_atk, rpt_def, function (err, rpt) {
                    if (!!err) {
                        console.error(err);
                        return next(null, {
                            code: Code.ARENA_CREATE_BATTLE_ERROR
                        });
                    }
                    if (!rpt) {
                        return next(null, {
                            code: Code.ARENA_CREATE_BATTLE_ERROR
                        });
                    }
                    battle_id = rpt.battle_id;
                    cb();
                });
            },
            function (cb) {
                // 设置挑战CD
                var arena_cd_time = constantUtil.value('arena_cd_time');
                arena_model.next_fight_tm = moment().unix() + arena_cd_time;
                cb();
            },
            function (cb) {
                player_manager.save(cb);
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return next(null, {
                    code: Code.FAIL
                });
            }

            return next(null, {
                code: Code.OK,
                result: {
                    record_id: battle_id,
                    atk: atk_info,
                    def: def_info
                }
            });
        }
    );
};

var _getAtkInfo = function (role_id, cb) {
    atkData.getDataForArena(role_id, 1, cb);
};

var _getDefPlayerInfo = function (role_id, cb) {
    atkData.getDataForArena(role_id, 2, cb);
};

var _getDefNpcInfo = function (npc_id) {
    return arenaData.getData(npc_id);
};

var _getVipLvl = function (player_manager, cb) {
    player_manager.getModel(['role', 'accrued'], function (err) {
        var role_model = player_manager.role;
        cb(null, role_model.vip);
    });
};
